<?php
declare(strict_types=1);

namespace LowCode;

use LowCode\Abstracts\Core;
use LowCode\Support\JsApi;
use LowCode\Traits\HasCall;
use LowCode\UI\JsonNode;

/**
 * @method static $this make(Block $block)
 * @method $this mode(string $mode = 'VNode' | 'Runtime' | 'Design' | 'Raw')
 * @method $this apis(array $apis)
 * @method $this meta(array $meta)
 * @method $this blocks(array $blocks)
 * @method $this dependencies(array $dependencies)
 * @method $this globals(array $globals)
 * @method $this assets(array $globals)
 * @method $this mock(bool $bool = true | false)
 */
class Page extends Core
{
    protected JsonNode $jsonNode;
    protected Store $store;

    protected static array $allowAttributes = [

    ];


    use HasCall;

    /**
     * @param Block $block
     */
    public function __construct(Block $block)
    {
        parent::__construct();
        $this->store = $block->getStore();
        $this->jsonNode = JsonNode::make();
        $this->jsonNode->schema($block);
    }

    /**
     * @param string $id
     * @return $this
     */
    public function id(string $id): static
    {
        return $this->setAttribute("id",$id);
    }

    protected function getProps($key = null)
    {
        $props = $this->jsonNode->get("props",[]);
        if ($key){
            return $props[$key]??[];
        }else{
            return $props;
        }
    }

    public function addApi(JsApi $jsApi): static
    {
        $apis = $this->getProps("apis");
        $apis[] = $jsApi;
        return $this->apis($apis);
    }

    public function addBlock(Block $block): static
    {
        $blocks = $this->getProps("blocks");
        $blocks[] = $block;
        return $this->blocks($blocks);
    }

    public function addDependencies(Dependencies $dependencies): static
    {
        $options = $this->getProps("dependencies");
        $options[] = $dependencies;
        return $this->dependencies($options);
    }

    public function addCss(string $link): static
    {
        $this->jsonNode->assetCss($link);
        return $this;
    }

    public function addJs(string $link): static
    {
        $this->jsonNode->assetJs($link);
        return $this;
    }

    public function addScript(string $script): static
    {
        $this->jsonNode->assetScript($script);
        return $this;
    }

    /**
     * @return array
     */
    public function toArray(): array
    {
        $this->store->buildPage($this, $this->jsonNode);
        $props = $this->getProps();
        foreach ($props as $key=>$value){
            if (!$value){
                unset($props[$key]);
            }
        }
        $this->attributes = array_merge($this->attributes, $props);
        $content = json_encode($this->attributes,JSON_UNESCAPED_UNICODE);
        $this->id(autoId("page_".md5($content)));
        return parent::toArray();
    }

    public function __call($method, $parameters)
    {
        if (method_exists($this->jsonNode,$method)){
            $this->jsonNode->$method(...$parameters);
            return $this;
        }
        return $this->toCall($method, $parameters);
    }

}
